﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using System.Collections;
using System.Diagnostics;

namespace GraphEditor
{
    class Entity
    {
        private String name;
        private Vector2 position;
        private float rotation; //degrees clockwise
        private float scale;
        private Texture2D texture;
        private int renderIndex;
        private bool isVisible;
        

        public Entity(String name, Vector2 position, Texture2D texture, int renderIndex) //this constructor uses default values, for the editor
        {
            this.name = name;
            this.position = position;
            this.texture = texture;
            this.renderIndex = renderIndex;

            rotation = 0; //default values
            scale = 1;
            isVisible = true;
        }

        public Entity(String name, Vector2 position, Texture2D texture, int renderIndex, bool isVisible, float rotation, float scale) //this constructor does not have default values
        {                                                                                                                             //for use in the engine
            this.name = name;
            this.position = position;
            this.texture = texture;
            this.renderIndex = renderIndex;
            this.isVisible = isVisible;
            this.rotation = rotation;
            this.scale = scale;
        }


        public override string ToString()
        {
            return name;
        }

        public String Name
        {
            get { return name; }
            set { name = value; }
        }

        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }

        public Texture2D Texture
        {
            get { return texture; }
            set { texture = value; }
        }

        public float Rotation
        {
            get { return rotation; }
            set { rotation = value; }
        }

        public float Scale
        {
            get { return scale; }
            set { scale = value; }
        }


        public void move(Vector2 movement)
        {
            position = Vector2.Add(position, movement);
        }

        

        public bool Visible()
        {
            return isVisible;
        }

        public int getRenderIndex()
        {
            return renderIndex;
        }
        
        virtual void update();


    }




    abstract class PlayableEntity : Entity
    {
        private bool playing;
        public PlayableEntity(String name, Vector2 position, Texture2D texture, int renderIndex) :
            base(name, position, texture, renderIndex)
        { }

        public PlayableEntity(String name, Vector2 position, Texture2D texture, int renderIndex, bool isVisible, float rotation, float scale) :
            base(name, position, texture, renderIndex, isVisible, rotation, scale)
        {}

        virtual void update();
        public void play(){ playing = true; }
        public void stop(){playing = false; }
        public bool isPlaying() {return playing;}
    }



    class AnimatedEntity : PlayableEntity
    {
        private bool looped;
        private List<Texture2D> textures;
        private float speed; //time between frames
        private float time; //total time

        public AnimatedEntity(String name, Vector2 position, List<Texture2D> textures, int renderIndex) : //has default values, for creating new objects in editor
            base(name, position, textures[0], renderIndex) //uses the first image from the animation
        {
            this.textures = textures;
            speed = 1;
            time = 0;
            looped = false;
        }

        public AnimatedEntity(String name, Vector2 position, List<Texture2D> textures, int renderIndex, bool isVisible, float rotation, float scale,
            bool looped, bool playing, float speed) :
            base(name, position, textures[0], renderIndex, isVisible, rotation, scale) //has no default values
        {
            this.looped = looped;
            if(playing) base.play();
            this.speed = speed;
            time = 0;
        }

        public void update(float dt)
        {
            if (!base.isPlaying()) return; //nothing to update if its not playing
            time = time + dt;
            int index = (int)((time / speed) % textures.Count);
            //draw things here?? not sure what to do here...
        }

        public bool Looped
        {
            get { return looped; }
            set { looped = value; }
        }

        public float Speed
        {
            get { return speed; }
            set { speed = value; }
        }

        public void loopAnimation()
        {
            looped = true;
        }




    }

    class SoundEntity : PlayableEntity
    {
        private SoundEffect s;
        public SoundEntity(String name, SoundEffect s)
            : base(name, null, null, 0)
        {
            this.s = s;
        }

        public void update() //not sure what this method does
        {
            if (!base.isPlaying()) return;
        }

        public SoundEffect Sound
        {
            get { return s; }
            set { s = value; }
        }
    }
}
